//
//  NetDownloadBooks.m
//  KidReading
//
//  Created by telen on 14/12/11.
//  Copyright (c) 2014年 刘赞黄Telen. All rights reserved.
//

#import "NetDownloadBooks.h"
#import "ConstDefine.h"

@implementation zipDownInfo
- (void)dealloc
{
    self.zipPath = nil;
}
@end

@implementation BookDownInfo

- (instancetype)init
{
    if (self = [super init]) {
        percentage = 0;
        self.countDownFailed = 0;
        self.countDownSuccess = 0;
        self.zipCount = 0;
        //self.zipsStatus = [NSMutableString new];
    }
    return self;
}

- (void)addpercentage:(float)per
{
    percentage += per;
    if (percentage >1) {
        percentage = 1;
        NSLog(@"百分比计算出错");
    }
}

- (float)getPer
{
    return percentage;
}

@end

@interface NetDownloadBooks()<TLReachabilityDelegate>
@end
@implementation NetDownloadBooks

static NetDownloadBooks* singleNetDownloadBooks = nil;
+ (NetDownloadBooks *)shareSingle
{
    if (!singleNetDownloadBooks) {
        singleNetDownloadBooks = [[NetDownloadBooks alloc] init];
    }
    return singleNetDownloadBooks;
}

- (instancetype)init
{
    if (self = [super init]) {
        noticeDelegateArr = [[NSMutableArray alloc] initWithCapacity:0];
        downingBooksInfoArr = [[NSMutableArray alloc] initWithCapacity:0];
        downQueue = [[NSMutableArray alloc] initWithCapacity:0];
        downIngQueue = [[NSMutableArray alloc] initWithCapacity:0];
        downBookQueueAllNet = [[NSMutableArray alloc] initWithCapacity:0];
        que_maxConcurrentOperationCount = 1;
        [[TLReachability shareInstance] registerNotice_delegate:self];
    }
    return self;
}

- (void)dealloc
{
    [[TLReachability shareInstance] unRegisterNotice_delegate:self];
}

- (void)registerDownBooksStatusNotice:(id<NetDownloadBooksNotice>)delegate
{
    NSValue* value = [NSValue valueWithNonretainedObject:delegate];
    [noticeDelegateArr addObject:value];
}

- (void)unRegisterDownBooksStatusNotice:(id<NetDownloadBooksNotice>)delegate
{
    NSArray* arr = [NSArray arrayWithArray:noticeDelegateArr];
    for (NSValue* value in arr) {
        if([value nonretainedObjectValue] == delegate){
            [noticeDelegateArr removeObject:value];
        }
    }
}

- (void)addDownQueueAllNet:(NSInteger)bookid
{
    [self removeDownQueueAllNet:bookid];
    [downBookQueueAllNet addObject:@(bookid)];
}

- (void)removeDownQueueAllNet:(NSInteger)bookid
{
    NSArray* arr = [NSArray arrayWithArray:downBookQueueAllNet];
    [arr enumerateObjectsUsingBlock:^(NSNumber*  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (bookid == obj.integerValue)[downBookQueueAllNet removeObject:obj];
    }];
}

- (BOOL)isInDownBookQueueAllNet:(NSInteger)bookid
{
    for (NSNumber* obj in downBookQueueAllNet) {
        if (bookid == obj.integerValue)return YES;
    }
    return NO;
}

- (BOOL)isDowneForBook:(NSInteger)bookid urlPath:(NSString*)urlpath edition:(long long)edition
{
    long long bookEdition = [[CacheData shareSingle] getEditionForDownIngBook:bookid];
    if(bookEdition == edition){
        NSString* zipPath = [DataProcessing storeZipPathForBookID:bookid urlPath:urlpath];
        if ([[NSFileManager defaultManager] fileExistsAtPath:zipPath]) {
            bool ret = [DataProcessing unZipBookZipPath:zipPath forBookid:bookid];
#if __IsToKeepLocalZip == 0
            if(!ret)[[NSFileManager defaultManager] removeItemAtPath:zipPath error:nil];
#endif
            return ret;
        }
    }else{
        NSString* zipPath = [DataProcessing storeZipPathForBookID:bookid urlPath:urlpath];
        if ([[NSFileManager defaultManager] fileExistsAtPath:zipPath]) {
            [[NSFileManager defaultManager] removeItemAtPath:zipPath error:nil];
        }
    }
    return NO;
}

- (void)downBooksUrl:(NSArray *)urlStrArr delegate:(id<NetDownloadBooksDelegate>)delegate withBookID:(NSInteger)bookid edition:(long long)edition withThroughDict:(NSDictionary *)throughDict allNetType:(BOOL)allnet
{
    if (allnet)[self addDownQueueAllNet:bookid];
    //
    [self downBooksUrl:urlStrArr delegate:delegate withBookID:bookid edition:edition withThroughDict:throughDict];
    //
}

- (void)downBooksUrl:(NSArray *)urlStrArr delegate:(id<NetDownloadBooksDelegate>)delegate withBookID:(NSInteger)bookid edition:(long long)edition withThroughDict:(NSDictionary *)throughDict
{
    [self downBooksUrl:urlStrArr relIndex:nil delegate:delegate withBookID:bookid edition:edition withThroughDict:throughDict];
}
- (void)downBooksUrl:(NSArray *)urlStrArr relIndex:(NSArray *)numArr delegate:(id<NetDownloadBooksDelegate>)delegate withBookID:(NSInteger)bookid edition:(long long)edition withThroughDict:(NSDictionary *)throughDict
{
    [DataProcessing do_Async_quick:^{
        for (BookDownInfo* bookdowninfo in downingBooksInfoArr) {
            if (bookdowninfo.bookid == bookid) {
                //
                NSLog(@"正在下载 %d 不可重复下载",(int)bookid);
                return;
            }
        }
        //准备下载通知
        for (NSValue* value in noticeDelegateArr) {
            id<NetDownloadBooksNotice> notice = [value nonretainedObjectValue];
            if ([notice respondsToSelector:@selector(netNotice_ReadyDownloadBook:)]) {
                [DataProcessing do_Main:^{
                    [notice netNotice_ReadyDownloadBook:bookid];
                } delay:0];
                
            }
        }
        //
        NSInteger count = urlStrArr.count;
        BookDownInfo* bookdowninfo = [[BookDownInfo alloc] init];
        [downingBooksInfoArr addObject:bookdowninfo];
        bookdowninfo.zipCount = count;
        bookdowninfo.bookid = bookid;
        bookdowninfo.bookEdition = edition;
        bookdowninfo.zipsStatus = [[NSMutableString alloc] initWithCapacity:count];
        for (NSInteger n=0; n<count; n++) {
            [bookdowninfo.zipsStatus appendString:@"0"];
        }
        for (NSInteger i =0; i<count; i++) {
            NSString* urlpath = [urlStrArr objectAtIndex:i];
            NSInteger realIndex = i;
            if (numArr && i < numArr.count) {
                realIndex = [numArr[i] integerValue];
            }
            //
            if ([self isDowneForBook:bookid urlPath:urlpath edition:edition]) {
                @synchronized(self){
                    [bookdowninfo addpercentage:1.0/bookdowninfo.zipCount];
                }
                NSInteger xx = 0;//1;
                for (NSInteger n =0; n<i; n++) {
                    //xx *= 10;
                    xx += 1;
                }
                //bookdowninfo.zipsStatus += xx;
                [bookdowninfo.zipsStatus replaceCharactersInRange:NSMakeRange(xx, 1) withString:@"1"];
                bookdowninfo.countDownSuccess += 1;
                //通知状态，需要解压成功
                NSInteger bookid = bookdowninfo.bookid;
                for (NSValue* value in noticeDelegateArr) {
                    id<NetDownloadBooksNotice> notice = [value nonretainedObjectValue];
                    if ([notice respondsToSelector:@selector(netNotice_DownloadBookFinishedOneZipIndex:bookID:)]) {
                        [DataProcessing do_Main:^{
                            [notice netNotice_DownloadBookFinishedOneZipIndex:realIndex bookID:bookid];
                        } delay:0];
                    }
                    if ([notice respondsToSelector:@selector(netNotice_DownloadBookFinishedOneZipIndex:bookID:throughDict:)]) {
                        [DataProcessing do_Main:^{
                            [notice netNotice_DownloadBookFinishedOneZipIndex:realIndex bookID:bookid throughDict:throughDict];
                        } delay:0];
                    }
                }
                continue;
            }else{
                [[CacheData shareSingle] updateBook:bookid DownEdition:edition];
            }
            //
            NSMutableDictionary* dict = [NSMutableDictionary new];
            if (throughDict) [dict setObject:throughDict forKey:__throughDict__];
            [dict setObject:bookdowninfo forKey:@"BookDownInfo"];
            [dict setObject:delegate forKey:@"delegate"];
            //
            zipDownInfo* zipdowninfo = [[zipDownInfo alloc] init];
            zipdowninfo.zipDownPercentage = 0;
            zipdowninfo.zipIndex = i;
            zipdowninfo.relZipIndex = realIndex;
            [dict setObject:zipdowninfo forKey:@"zipDownInfo"];
            //
            NSURL* url = [NSURL URLWithString:[DataProcessing fullBookZipFileUrl:urlpath]];
            
            NSString* tempPath = [DataProcessing tempZipPathForBookID:bookid urlPath:urlpath];
            NSString* zipPath = [DataProcessing storeZipPathForBookID:bookid urlPath:urlpath];
            //
            zipdowninfo.zipPath = zipPath;
            JRASIHTTPRequest* asihttprequest = [JRASIHTTPRequest requestWithURL:url];
            asihttprequest.tag = bookid;
            [asihttprequest setTemporaryFileDownloadPath:tempPath];
            [asihttprequest setDownloadDestinationPath:zipPath];
            [asihttprequest setUserInfo:dict];
            [asihttprequest setDelegate:self];
            [asihttprequest setDownloadProgressDelegate:self];
            [asihttprequest setAllowResumeForFileDownloads:NO];//开关断点下载
            [asihttprequest setTimeOutSeconds:120];//设置单个包最大允许120秒下载时长
            [asihttprequest setShouldContinueWhenAppEntersBackground:YES];//后台继续下载
            //[asihttprequest startAsynchronous];
            @synchronized (@"queDown") {
                [self queDown:asihttprequest];
            }
        }
    }];
}

- (JRASIHTTPRequest*)copyBookDownRequest:(JRASIHTTPRequest*)request
{
    JRASIHTTPRequest* asihttprequest = [JRASIHTTPRequest requestWithURL:request.url];
    asihttprequest.tag = request.tag;
    [asihttprequest setTemporaryFileDownloadPath:request.temporaryFileDownloadPath];
    [asihttprequest setDownloadDestinationPath:request.downloadDestinationPath];
    [asihttprequest setUserInfo:request.userInfo];
    [asihttprequest setDelegate:self];
    [asihttprequest setDownloadProgressDelegate:self];
    [asihttprequest setAllowResumeForFileDownloads:NO];//开关断点下载
    [asihttprequest setTimeOutSeconds:120];//设置单个包最大允许120秒下载时长
    return asihttprequest;
}

- (void)cancelDownBooks:(NSInteger)bookid
{
    NSArray* arr = [NSArray arrayWithArray:downQueue];
    for (JRASIHTTPRequest* req in arr) {
        if (req.tag == bookid) {
            [downQueue removeObject:req];
        }
    }
    arr = [NSArray arrayWithArray:downIngQueue];
    for (JRASIHTTPRequest* req in arr) {
        if (req.tag == bookid) {
            [req cancel];
            [downIngQueue removeObject:req];
        }
    }
    arr = [NSArray arrayWithArray:downingBooksInfoArr];
    for (BookDownInfo* bookdowninfo in arr) {
        if (bookdowninfo.bookid == bookid) {
            [downingBooksInfoArr removeObject:bookdowninfo];
        }
    }
    [self removeDownQueueAllNet:bookid];
    //
    //已经取消通知
    for (NSValue* value in noticeDelegateArr) {
        id<NetDownloadBooksNotice> notice = [value nonretainedObjectValue];
        if ([notice respondsToSelector:@selector(netNotice_CancelDownloadBook:)]) {
            [DataProcessing do_Main:^{
                [notice netNotice_CancelDownloadBook:bookid];
            } delay:0];
        }
    }
}

- (void)cancelDownBooksAll
{
    NSArray* arr = [NSArray arrayWithArray:downQueue];
    for (JRASIHTTPRequest* req in arr) {
            [downQueue removeObject:req];
    }
    arr = [NSArray arrayWithArray:downIngQueue];
    for (JRASIHTTPRequest* req in arr) {
            [req cancel];
            [downIngQueue removeObject:req];
    }
    arr = [NSArray arrayWithArray:downingBooksInfoArr];
    for (BookDownInfo* bookdowninfo in arr) {
            [downingBooksInfoArr removeObject:bookdowninfo];
    }
    [downBookQueueAllNet removeAllObjects];
}

- (void)queDown:(JRASIHTTPRequest*)request
{
    TLReachability* tlReachability = [TLReachability shareInstance];
    BOOL isWiFiOK = tlReachability.wifiStatus;
    BOOL isNetOK = tlReachability.netStatus;
    BOOL isForAllNet = [self isInDownBookQueueAllNet:request.tag];
    //
    if(isForAllNet || (isNetOK && isWiFiOK)){
        if (request && downIngQueue.count < que_maxConcurrentOperationCount) {
            [downIngQueue addObject:request];
            [request startAsynchronous];
        }else{
            if(request)[downQueue addObject:request];
        }
    }else{
        if(request)[downQueue addObject:request];
    }
}

- (void)queRemove:(JRASIHTTPRequest*)request
{
    NSArray* arr = [NSArray arrayWithArray:downQueue];
    for (JRASIHTTPRequest* req in arr) {
        if (req == request) {
            [downQueue removeObject:request];
            break;
        }
    }
    arr = [NSArray arrayWithArray:downIngQueue];
    for (JRASIHTTPRequest* req in arr) {
        if (req == request) {
            [request cancel];
            [downIngQueue removeObject:request];
            break;
        }
    }
}

- (void)queRemoveIng:(JRASIHTTPRequest*)request
{
    NSArray* arr = [NSArray arrayWithArray:downIngQueue];
    for (JRASIHTTPRequest* req in arr) {
        if (req == request) {
            [request cancel];
            [downIngQueue removeObject:request];
            break;
        }
    }
}

- (void)queNext
{
    TLReachability* tlReachability = [TLReachability shareInstance];
    BOOL isWiFiOK = tlReachability.wifiStatus;
    BOOL isNetOK = tlReachability.netStatus;
    if (isNetOK && downIngQueue.count < que_maxConcurrentOperationCount && downQueue.count > 0) {
        JRASIHTTPRequest* request = [downQueue objectAtIndex:0];
        //
        BOOL isForAllNet = [self isInDownBookQueueAllNet:request.tag];
        //
        if(isForAllNet || (isNetOK && isWiFiOK)){
            [downIngQueue addObject:request];
            [request startAsynchronous];
            //
            [downQueue removeObject:request];
        }
    }
}

- (NSArray *)getAllWaitingDownBooks
{
    NSMutableArray* arr = [NSMutableArray arrayWithCapacity:0];
    for (BookDownInfo* bookdowninfo in downingBooksInfoArr) {
        BOOL isWaiting = YES;
        for (JRASIHTTPRequest* req in downIngQueue) {
            if (req.tag == bookdowninfo.bookid) {
                isWaiting = NO;
                break;
            }
        }
        if(isWaiting)[arr addObject:[NSNumber numberWithInteger:bookdowninfo.bookid]];
    }
    return arr;
}

- (BOOL)isBookDownWaiting:(NSInteger)bookid
{
    for (BookDownInfo* bookdowninfo in downingBooksInfoArr) {
        if (bookdowninfo.bookid == bookid) {
            BOOL isWaiting = YES;
            for (JRASIHTTPRequest* req in downIngQueue) {
                if (req.tag == bookdowninfo.bookid) {
                    isWaiting = NO;
                    break;
                }
            }
            return isWaiting;
        }
    }
    return NO;
}

- (BOOL)isBookDowning:(NSInteger)bookid
{
    for (JRASIHTTPRequest* req in downIngQueue) {
        if (req.tag == bookid) {
            return YES;
            break;
        }
    }
    return NO;
}

- (CGFloat)getBookDowningPer:(NSInteger)bookid
{
    if ([self isBookDowning:bookid]) {
        for (BookDownInfo* bookdowninfo in downingBooksInfoArr) {
            if (bookdowninfo.bookid == bookid) {
                return bookdowninfo.getPer;
            }
        }
    }
    return 0;
}

- (NSString *)getDownStatusForBook:(NSInteger)bookid
{
    BOOL isBookDowne = [[CacheData shareSingle] isBookDownDoneWithBookId:bookid];
    if (isBookDowne) {
        return @"1";
    }
    for (BookDownInfo* bookdowninfo in downingBooksInfoArr) {
        if (bookdowninfo.bookid == bookid) {
            return bookdowninfo.zipsStatus;
        }
    }
    return 0;
}

- (void)requestStarted:(JRASIHTTPRequest *)request{}

- (void)request:(JRASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders
{
    NSMutableDictionary* userInfo = (NSMutableDictionary*)[request userInfo];
    zipDownInfo* zipdowninfo = [userInfo objectForKey:@"zipDownInfo"];
    if([responseHeaders objectForKey:@"Content-Length"]){
        zipdowninfo.zipSize = [[responseHeaders objectForKey:@"Content-Length"] longLongValue];
    }
    //
    //处理服务器通知信息
    if (zipdowninfo.zipIndex == 0) {
        BookDownInfo* bookdowninfo = [userInfo objectForKey:@"BookDownInfo"];
        /*
        NSString* uid = [NSString stringWithFormat:@"%d",(int)[CacheData shareSingle].getUserLoginInfo.uid];
        NSString* pid = [NSString stringWithFormat:@"%d",(int)bookdowninfo.bookid];
        NSString* edt = [NSString stringWithFormat:@"%d",(int)bookdowninfo.bookEdition];
        NSString *currentTime = [[NSString alloc] initWithFormat:@"%0.f",[[NSDate date] timeIntervalSince1970]];
        NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:currentTime,@"optime",@"downloadadd",@"op",uid,@"uid",pid,@"pid",edt,@"edt",@"begin",@"status", nil];
        [[NetRequest shareSingle] askNet:__URL_PortBooks_ refsDict:dict delegate:nil withThroughDict:nil];
         */
        //
        NSInteger bookid = bookdowninfo.bookid;
        id<NetDownloadBooksDelegate> delegate = [[request userInfo] objectForKey:@"delegate"];
        if (delegate && [delegate respondsToSelector:@selector(netDownloadBooksPercentage:bookID:)]) {
            [delegate netDownloadBooksPercentage:0 bookID:bookid];
        }
    }
    //
#if __Debug_Net
    NSLog(@"%@",responseHeaders);
#endif
}

//- (void)unZipForBookWithZipPath:(NSString *)zipPath tbBook:()

- (void)requestFinished:(JRASIHTTPRequest *)request
{
#if __Debug_Net
    NSString* str2 = [request responseStatusMessage];
    NSString* str1 = [request responseString];
    NSLog(@"requestStatus:%@  requestMsg:%@",str2,str1);
    NSLog(@"URL: %@",[request url]);
#endif
    NSMutableDictionary* userInfo = (NSMutableDictionary*)[request userInfo];
    zipDownInfo* zipdowninfo = [userInfo objectForKey:@"zipDownInfo"];
    BookDownInfo* bookdowninfo = [userInfo objectForKey:@"BookDownInfo"];
    //
    NSDictionary* throughDict = [userInfo objectForKey:__throughDict__];
    id tbBook = [throughDict valueForKey:@"TB_Book"];
    //Class tbClass=NSClassFromString(@"TABLE_BOOKS");
    //NSLog(@"tbBook readsource--%@",tbBook.readSource);
    //解压
    BOOL restult = NO;
    if (zipdowninfo.zipPath) {
#ifdef JR_PJ
        NSNumber *retNum = [NSObject msgToTarget:self menthed:@"unZipQuizPathWithZipPath:tbBook:" refs:@[zipdowninfo.zipPath, tbBook] needReturnValue:YES];
        restult = [retNum boolValue];
#else
        restult = [DataProcessing unZipBookZipPath:zipdowninfo.zipPath forBookid:bookdowninfo.bookid];
#endif
    }
    
    if (restult) {
        NSInteger xx = 0;//1;
        for (NSInteger n =0; n<zipdowninfo.zipIndex; n++) {
            //xx *= 10;
            xx += 1;
        }
        [bookdowninfo.zipsStatus replaceCharactersInRange:NSMakeRange(xx, 1) withString:@"1"];
        bookdowninfo.countDownSuccess += 1;
    }else{
        bookdowninfo.countDownFailed += 1;
        [[WaitingShow shareSingleShow] showString:NSLocalizedString(@"unZipFileFail", "") andAutoHide:YES];
        NSLog(@"解压失败url: %@",request.originalURL);
    }
    
    //下载回执 无需解压成功
    id<NetDownloadBooksDelegate> delegate = [[request userInfo] objectForKey:@"delegate"];
    if (delegate && [delegate respondsToSelector:@selector(netDownloadBookOneZipFinished:)]) {
        //if(throughDict)[userInfo removeObjectForKey:__throughDict__];
        NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:userInfo,__DownBooksInfo__, nil];
        if (throughDict) [dict setObject:throughDict forKey:__throughDict__];
        [delegate netDownloadBookOneZipFinished:dict];
    }
    //通知状态，需要解压成功
    NSInteger bookid = bookdowninfo.bookid;
    if(restult)for (NSValue* value in noticeDelegateArr) {
        id<NetDownloadBooksNotice> notice = [value nonretainedObjectValue];
        if ([notice respondsToSelector:@selector(netNotice_DownloadBookFinishedOneZipIndex:bookID:)]) {
            [DataProcessing do_Main:^{
                 [notice netNotice_DownloadBookFinishedOneZipIndex:zipdowninfo.relZipIndex bookID:bookid];
            } delay:0];
        }
        if ([notice respondsToSelector:@selector(netNotice_DownloadBookFinishedOneZipIndex:bookID:throughDict:)]) {
            [DataProcessing do_Main:^{
                [notice netNotice_DownloadBookFinishedOneZipIndex:zipdowninfo.relZipIndex bookID:bookid throughDict:throughDict];
            } delay:0];
        }
    }
    //
    if (bookdowninfo.zipCount == bookdowninfo.countDownSuccess) {
        [self downSuccessOpreationWithBookDownInfo:bookdowninfo];
#if __IsToKeepLocalZip == 0
        [DataProcessing deleteBookZips:bookid];
#endif
        for (NSValue* value in noticeDelegateArr) {
            id<NetDownloadBooksNotice> notice = [value nonretainedObjectValue];
            if ([notice respondsToSelector:@selector(netNotice_DownloadBooksAllFinished:)]) {
                [DataProcessing do_Main:^{
                    [notice netNotice_DownloadBooksAllFinished:bookid];
                } delay:0];
            }
            if ([notice respondsToSelector:@selector(netNotice_DownloadBooksAllFinished:throughDict:)]) {
                [DataProcessing do_Main:^{
                    [notice netNotice_DownloadBooksAllFinished:bookid throughDict:throughDict];
                } delay:0];
            }
        }
        //处理服务器通知信息
        /*
        NSString* uid = [NSString stringWithFormat:@"%d",(int)[CacheData shareSingle].getUserLoginInfo.uid];
        NSString* pid = [NSString stringWithFormat:@"%d",(int)bookdowninfo.bookid];
        NSString* edt = [NSString stringWithFormat:@"%d",(int)bookdowninfo.bookEdition];
        NSString *currentTime = [[NSString alloc] initWithFormat:@"%0.f",[[NSDate date] timeIntervalSince1970]];
        NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:currentTime,@"optime",@"downloadadd",@"op",uid,@"uid",pid,@"pid",edt,@"edt",@"complete",@"status", nil];
        [[NetRequest shareSingle] askNet:__URL_PortBooks_ refsDict:dict delegate:nil withThroughDict:nil];
         */
    }
    else if (bookdowninfo.zipCount == bookdowninfo.countDownSuccess+ bookdowninfo.countDownFailed) {
        [downingBooksInfoArr removeObject:bookdowninfo];
        for (NSValue* value in noticeDelegateArr) {
            id<NetDownloadBooksNotice> notice = [value nonretainedObjectValue];
            if ([notice respondsToSelector:@selector(netNotice_DownloadBooksAllEndHasFailed:)]) {
                [DataProcessing do_Main:^{
                    [notice netNotice_DownloadBooksAllEndHasFailed:bookid];
                } delay:0];
            }
        }
        //[[WaitingShow shareSingleShow] showString:NSLocalizedString(@"bookDownFail", "") andAutoHide:YES];
    }
    //
    if (bookdowninfo.zipCount == bookdowninfo.countDownSuccess+ bookdowninfo.countDownFailed) {
        [self removeDownQueueAllNet:bookid];
    }
    //
    @synchronized (@"queDown") {
        [self queRemoveIng:request];
        [self queNext];
    }
}

- (void)downSuccessOpreationWithBookDownInfo:(BookDownInfo *)bookdowninfo {
    [[CacheData shareSingle] updateBook:bookdowninfo.bookid CacheEdition:bookdowninfo.bookEdition];
    UserInfo* uinfo = [[CacheData shareSingle] getUserLoginInfo];
    [[CacheData shareSingle] updateBook:bookdowninfo.bookid CacheEdition:bookdowninfo.bookEdition forUid:uinfo.uid];
    [downingBooksInfoArr removeObject:bookdowninfo];
}


- (void)requestFailed:(JRASIHTTPRequest *)request
{
#if __Debug_Net || __Debug_Net_Error
    NSString* str1 = [request responseString];
    NSString* str2 = [request responseStatusMessage];
    NSLog(@"requestStatus:%@  requestMsg:%@",str2,str1);
    NSURL* url = [request url];
    NSLog(@"requestFailed:errorURL: %@",url);
    NSLog(@"error: %@",request.error);
#endif
    NSMutableDictionary* userInfo = (NSMutableDictionary*)[request userInfo];
    BookDownInfo* bookdowninfo = [userInfo objectForKey:@"BookDownInfo"];
    if (!request.cancelled) {
        bookdowninfo.countDownFailed += 1;
    }
    //
    id<NetDownloadBooksDelegate> delegate = [[request userInfo] objectForKey:@"delegate"];
    if (delegate && [delegate respondsToSelector:@selector(netDownloadBookOneZipFailed:)]) {
        NSDictionary* throughDict = [userInfo objectForKey:__throughDict__];
        //if(throughDict)[userInfo removeObjectForKey:__throughDict__];
        NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:userInfo,__DownBooksInfo__, nil];
        if (throughDict) [dict setObject:throughDict forKey:__throughDict__];
        [delegate netDownloadBookOneZipFailed:dict];
    }
    //
    NSInteger bookid = bookdowninfo.bookid;
    if (bookdowninfo.zipCount == bookdowninfo.countDownSuccess+ bookdowninfo.countDownFailed) {
        [downingBooksInfoArr removeObject:bookdowninfo];
        for (NSValue* value in noticeDelegateArr) {
            id<NetDownloadBooksNotice> notice = [value nonretainedObjectValue];
            if ([notice respondsToSelector:@selector(netNotice_DownloadBooksAllEndHasFailed:)]) {
                [DataProcessing do_Main:^{
                    [notice netNotice_DownloadBooksAllEndHasFailed:bookid];
                } delay:0];
            }
        }
        if(!request.cancelled)[[WaitingShow shareSingleShow] showString:NSLocalizedString(@"bookDownFail", "") andAutoHide:YES];
    }
    //
    if(request.cancelled)for (NSValue* value in noticeDelegateArr) {
        id<NetDownloadBooksNotice> notice = [value nonretainedObjectValue];
        if ([notice respondsToSelector:@selector(netNotice_CancelDownloadBook:)]) {
            [DataProcessing do_Main:^{
                [notice netNotice_CancelDownloadBook:bookid];
            } delay:0];
        }
    }
    //
    [DataProcessing do_Async:^{
        //
        TLReachability* tlReachability = [TLReachability shareInstance];
        BOOL isNetOK = tlReachability.netStatus;
        if (isNetOK && bookdowninfo.zipCount == bookdowninfo.countDownSuccess+ bookdowninfo.countDownFailed) {
            [self removeDownQueueAllNet:bookid];
        }
        //
        @synchronized (@"queDown") {
            [self queRemove:request];
            [self queNext];
        }
    } delay:0.3f];
    //
    //if(!request.cancelled)[[WaitingShow shareSingleShow] showString:NSLocalizedString(@"netRequestFail", "") andAutoHide:YES];
}

//断点续传时候，会有用
- (void)request:(JRASIHTTPRequest *)request incrementDownloadSizeBy:(long long)newLength
{
    NSMutableDictionary* userInfo = (NSMutableDictionary*)[request userInfo];
    zipDownInfo* zipdowninfo = [userInfo objectForKey:@"zipDownInfo"];
    zipdowninfo.zipSize = newLength;
}

- (void)request:(JRASIHTTPRequest *)request didReceiveBytes:(long long)bytes
{
    NSMutableDictionary* userInfo = (NSMutableDictionary*)[request userInfo];
    zipDownInfo* zipdowninfo = [userInfo objectForKey:@"zipDownInfo"];
    BookDownInfo* bookdowninfo = [userInfo objectForKey:@"BookDownInfo"];
    zipdowninfo.zipDownPercentage += bytes/(float)zipdowninfo.zipSize;
    //
    @synchronized(self){
        [bookdowninfo addpercentage:(bytes/(float)zipdowninfo.zipSize)/bookdowninfo.zipCount];
    }
    //
    NSInteger bookid = bookdowninfo.bookid;
    id<NetDownloadBooksDelegate> delegate = [[request userInfo] objectForKey:@"delegate"];
    if (delegate && [delegate respondsToSelector:@selector(netDownloadBooksPercentage:bookID:)]) {
        [delegate netDownloadBooksPercentage:bookdowninfo.getPer bookID:bookid];
    }
    //
    for (NSValue* value in noticeDelegateArr) {
        id<NetDownloadBooksNotice> notice = [value nonretainedObjectValue];
        if ([notice respondsToSelector:@selector(netNotice_DownloadBooksPercentage:bookID:)]) {
            [DataProcessing do_Main:^{
                [notice netNotice_DownloadBooksPercentage:bookdowninfo.getPer bookID:bookid];
            } delay:0];
        }
    }
    //
#if __Debug_Net
    NSLog(@"zipIndex:%d size:%lld  count:%d <--> %lld <-->%f <-->%f",zipdowninfo.zipIndex,zipdowninfo.zipSize,(int)bookdowninfo.zipCount,bytes,zipdowninfo.zipDownPercentage,bookdowninfo.getPer);
#endif
}

#pragma mark-
- (void)tlReachabilityNetStatusChanged:(TLReachability *)tlReachability
{
    BOOL isWiFiOK = tlReachability.wifiStatus;
    BOOL isNetOK = tlReachability.netStatus;
    //网络wifi
    if(isNetOK && isWiFiOK){
        [DataProcessing do_Async:^{
            @synchronized (@"queDown") {
                [self queNext];
            }
        } delay:0.3];
    }
    //无网
    if (!isNetOK) {
        NSArray* arr = [NSArray arrayWithArray:downIngQueue];
        for (JRASIHTTPRequest* req in arr) {
            JRASIHTTPRequest* request = [self copyBookDownRequest:req];
            [req cancel];
            [downQueue insertObject:request atIndex:0];
            [downIngQueue removeObject:req];
            //
            //准备下载通知
            for (NSValue* value in noticeDelegateArr) {
                id<NetDownloadBooksNotice> notice = [value nonretainedObjectValue];
                if ([notice respondsToSelector:@selector(netNotice_ReadyDownloadBook:)]) {
                    [DataProcessing do_Main:^{
                        [notice netNotice_ReadyDownloadBook:req.tag];
                    } delay:0];
                }
            }
            
        }
    }
    //无wifi 有网
    if(isNetOK && !isWiFiOK){
        NSArray* arr = [NSArray arrayWithArray:downIngQueue];
        for (JRASIHTTPRequest* req in arr) {
            BOOL isForAllNet = [self isInDownBookQueueAllNet:req.tag];
            if(!isForAllNet){
                JRASIHTTPRequest* request = [self copyBookDownRequest:req];
                [req cancel];
                [downQueue insertObject:request atIndex:0];
                [downIngQueue removeObject:req];
                [DataProcessing do_Async:^{
                    @synchronized (@"queDown") {
                        [self queNext];
                    }
                } delay:0.3];
                //
                //准备下载通知
                for (NSValue* value in noticeDelegateArr) {
                    id<NetDownloadBooksNotice> notice = [value nonretainedObjectValue];
                    if ([notice respondsToSelector:@selector(netNotice_ReadyDownloadBook:)]) {
                        [DataProcessing do_Main:^{
                            [notice netNotice_ReadyDownloadBook:req.tag];
                        } delay:0];
                    }
                }
            }
        }
    }
}

@end
